<template>
  <div class="img-upload">
    <div class="img-upload-box">
      <div v-for="file in modelValue" :key="file" class="img-upload-item el-upload-list--picture-card">
        <el-image
          class="el-upload-list__item-thumbnail"
          :src="file"
          :alt="file"
        />
        <span class="el-upload-list__item-actions">
          <span
            class="el-upload-list__item-preview"
            @click="handlePreview(file)"
          >
            <c-icon name="ZoomIn"></c-icon>
          </span>
          <span
            v-if="!disabled"
            class="el-upload-list__item-delete"
            @click="handleRemove(file)"
          >
            <c-icon name="Delete"></c-icon>
          </span>
        </span>
      </div>
    </div>
    <el-upload
      v-if="modelValue.length < maxCount"
      accept="image/*"
      list-type="picture-card"
      :action="uploadUrl"
      :multiple="multiple"
      :limit="maxCount"
      :show-file-list="false"
      :file-list="fileList"
      :headers="{ Authorization: token }"
      :before-upload="beforeUpload"
      :on-success="handleUploadSuccess"
      :on-error="handleError"
      :on-exceed="handleExceed"
    >
      <!-- 如果图片列表数量>=maxCount,不显示加号 -->
      <c-icon name="Plus"></c-icon>
    </el-upload>
    <div class="el-upload__tip">
      <div class="text" v-for="t in tips" :key="t">· {{ t }}</div>
    </div>
    <el-dialog custom-class="img-preview-dialog" :append-to-body="true" v-model="dialogVisible" title="图片预览">
      <el-image :src="dialogImageUrl" alt="" />
    </el-dialog>
  </div>
</template>
<script>
import { uploadUrl } from '@/api/material';
import { uploadBaseURL } from '@/api/request.js';
import { replaceUrl } from '@/utils/utils';

export default {
  name: 'MultipleImgUpload',
  props: {
    // 图片属性数组
    modelValue: {
      type: Array,
      default: () => [],
    },
    // 最大上传图片数量
    maxCount: {
      type: Number,
      default: 1,
    },
    tips: {
      type: Array,
      default() {
        return ['建议尺寸：400*200px', '大小：不超过2M', '格式：支持jpg、jpeg、png、gif'];
      },
    },
    disabled: Boolean,
    multiple: {
      type: Boolean,
      default: true,
    },
  },
  emits: ['success'],
  data() {
    return {
      fileList: [],
      uploadUrl: `${uploadBaseURL}${replaceUrl(uploadUrl)}`,
      dialogVisible: false,
      dialogImageUrl: null,
    };
  },
  computed: {
    token() {
      return this.$store.state.common.token;
    },
  },
  methods: {
    emitInput(fileList) {
      this.$emit('success', fileList);
    },
    handleRemove(file) {
      const index = this.modelValue.findIndex(ff => ff === file);
      const list = [...this.modelValue];
      list.splice(index, 1);
      this.emitInput(list);
    },
    handlePreview(file) {
      this.dialogVisible = true;
      this.dialogImageUrl = file;
    },
    beforeUpload(file) {
      const isJPG = file.type.includes('image/');
      const isLt2M = file.size / 1024 / 1024 < 2;

      if (!isJPG) {
        this.$message.error('上传图片只能是 JPG, JPEG, PNG, GIF 格式!');
      }
      if (!isLt2M) {
        this.$message.error('上传图片大小不能超过 2MB!');
      }
      return isJPG && isLt2M;
    },
    handleUploadSuccess(res) {
      if (res.code === 401) {
        this.$router.push({
          path: '/login',
          query: {
            to: this.$route.path,
          },
        });
        return;
      }
      if (res.code !== 200) {
        this.$message.error(res.msg);
        this.fileList = [];
        return;
      }
      const data = res.data || [];
      const that = this;
      setTimeout(() => {
        const list = [...that.modelValue];
        list.push(data[0]);
        that.emitInput(list);
      }, 0);
    },
    handleError(err) {
      this.$message.error(err.msg || '上传错误');
    },
    handleExceed() {
      this.$message({
        message: `最多只能上传${this.maxCount}张图片`,
        type: 'warning',
      });
    },
  },
};
</script>
<style lang="less" scoped>
.img-upload {
  &-box {
    display: flex;
    justify-content: flex-start;
    flex-wrap: wrap;
    .img-upload-item {
      width: 60px;
      height: 60px;
      display: flex;
      justify-content: center;
      align-items: center;
      position: relative;
      overflow: hidden;
      border-radius: 8px;
      border: 1px dashed #c0ccda;
      margin: 10px 10px 10px 0;
      padding: 10px;
    }
  }
  :deep(.el-upload__tip) {
    line-height: 18px;
  }
  :deep(.el-upload--picture-card) {
    height: 80px;
    width: 80px;
    line-height: 80px;
    display: flex;
    justify-content: center;
    align-items: center;
    i {
      margin-top: inherit;
    }
  }
  :deep(.el-upload-list__item-thumbnail) {
    height: auto;
  }
}
.img-preview-dialog {
  :deep(.el-dialog__body) {
    text-align: center;
    img {
      max-width: 100%;
    }
  }
}
</style>
